package com.zf.bm.common.core.base.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Maps;
import com.zf.bm.common.core.sys.entity.User;
import com.zf.bm.common.utils.SpringContextHolder;
import com.zf.bm.common.validator.BeanValidators;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.hibernate.validator.constraints.Length;

import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Entity支持类
 */
@Slf4j
public abstract class BaseEntity<T extends Model<T>> extends Model<T> {


    /**
     * 实体编号（唯一标识）
     */
    //ID_WORKER 生成主键太长导致 js 精度丢失  @JsonSerialize(using= ToStringSerializer.class)
//    @JsonSerialize(using= ToStringSerializer.class)
    protected Long id;
    @TableField(fill = FieldFill.INSERT)
    protected User createBy;    // 创建者
    @TableField(fill = FieldFill.INSERT_UPDATE)
    protected User updateBy;    // 更新者
    @TableField(fill = FieldFill.INSERT)
    protected Date createDate;    // 创建日期
    @TableField(fill = FieldFill.INSERT_UPDATE)
    protected Date updateDate;    // 更新日期
    protected String remarks;    // 备注
    @TableLogic
    protected String delFlag;    // 删除标记（0：正常；1：删除；2：审核）
    @TableField(exist = false)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String errors ;//后台字段验证错误信息
    /**
     * 每页显示条数，默认 10
     */
    @TableField(exist = false)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    protected Long size = 20L;
    /**
     * 当前页
     */
    @TableField(exist = false)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    protected Long current = 1L;

    /**
     * 当前实体分页对象
     */
    @TableField(exist = false)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    protected Page<T> page;

    @TableField(exist = false)
    private String order;

    @TableField(exist = false)
    private Integer sortType;

    /**
     * 自定义SQL（SQL标识，SQL内容）
     */
    @TableField(exist = false)
    protected Map<String, String> sqlMap;

    /**
     * 验证Bean实例对象
     */
    @TableField(exist = false)
    protected transient Validator validator = SpringContextHolder.getBean(Validator.class);


    public BaseEntity() {
        this.delFlag = DEL_FLAG_NORMAL;
    }

    public BaseEntity(Long id) {
        this();
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public IPage<T> getPage() {
        if (page == null) {
            page = new Page<T>(current, size);
        }
        return page;
    }

    @JsonIgnore
    public Map<String, String> getSqlMap() {
        if (sqlMap == null) {
            sqlMap = Maps.newHashMap();
        }
        return sqlMap;
    }

    @JsonIgnore
    public User getCreateBy() {
        return createBy;
    }

    public void setCreateBy(User createBy) {
        this.createBy = createBy;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @JsonIgnore
    public User getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(User updateBy) {
        this.updateBy = updateBy;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }


    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }

    @Length(min = 0, max = 255)
    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }


    @JsonIgnore
    @Length(min = 1, max = 1)
    public String getDelFlag() {
        return delFlag;
    }

    public void setDelFlag(String delFlag) {
        this.delFlag = delFlag;
    }

    public void setSize(Long size) {
        this.size = size;
    }

    public void setCurrent(Long current) {
        this.current = current;
    }

    public Long getCurrent() {
        return current;
    }

    public Long getSize() {
        return size;
    }

    public String getErrors() {
        return errors;
    }

    public void setErrors(String errors) {
        this.errors = errors;
    }

    @Override
    public boolean insert() {
        if (!beanValidator()) {
            return false;
        }
        return super.insert();
    }

    @Override
    public boolean insertOrUpdate() {
        if (!beanValidator()) {
            return false;
        }
        return super.insertOrUpdate();
    }

    @Override
    public boolean updateById() {
        if (!beanValidator()) {
            return false;
        }
        return super.updateById();
    }

    @Override
    public boolean update(Wrapper<T> updateWrapper) {
        if (!beanValidator()) {
            return false;
        }
        return super.update(updateWrapper);
    }

    /**
     * 服务端参数有效性验证
     *
     * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
     */
    protected boolean beanValidator() {
        try {
            BeanValidators.validateWithException(validator, this);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            StringBuilder message = new StringBuilder();
            for(String msg : list){
                message.append(msg).append("\n");
            }
            this.setErrors(message.toString());
            log.error("数据验证失败:{}", list);
            return false;
        }
        return true;
    }

    /**
     * 删除标记（0：正常；1：删除；2：审核；）
     */
    public static final String DEL_FLAG_NORMAL = "0";
    public static final String DEL_FLAG_DELETE = "1";


    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public Integer getSortType() {
        return sortType;
    }

    public void setSortType(Integer sortType) {
        this.sortType = sortType;
    }
}
